package com.jintu.portal.service.datadriver;

import com.alibaba.fastjson.JSONObject;
import com.jintu.portal.config.Constant;
import com.jintu.portal.pojo.RetEntity;
import com.jintu.portal.service.datadriver.parser.DataParser;
import com.jintu.portal.service.datadriver.parser.DataParserGetter;
import com.jintu.portal.cache.RedisHelper;
import com.jintu.portal.mq.RabbitMqSender;
import com.jintu.portal.pojo.entity.mysql.ParamDataSource;
import com.jintu.portal.pojo.mq.NotificationEntity;
import com.jintu.portal.pojo.submit.DataRequest;
import com.jintu.portal.pojo.submit.DataResponse;
import com.jintu.portal.service.DataGetter;
import com.jintu.portal.utils.CommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Random;

/**
 * @author very
 */
@Slf4j
@Component("datadriverGetter")
public class DatadriverGetter implements DataGetter {

    @Resource(name = "dataRequestHandler")
    private DataRequestHandler dataRequestHandler;

    @Resource(name = "dataParserGetter")
    private DataParserGetter dataParserGetter;

    @Resource(name = "rabbitMqSender")
    private RabbitMqSender rabbitMqSender;

    @Resource(name = "redisHelper")
    private RedisHelper redisHelper;

    @Resource
    private CompleteRequestHelper completeRequestHelper;

    @Override
    public DataResponse requestDataFromParamDataSource(Integer userId, DataRequest dataRequest, ParamDataSource paramDataSource, JSONObject orderCache) throws Exception {
        String requestOrderId = genDataRequestOrderId(dataRequest);
        String responseContent;
        try {
            JSONObject merchPrivate = new JSONObject();
            merchPrivate.put("userId", userId);
            merchPrivate.put("username", dataRequest.getUsername());
            merchPrivate.put("orderId", dataRequest.getOrderId());
            merchPrivate.put("dataSourceCode", dataRequest.getDataSourceCode());
            merchPrivate.put("dataSourceInterface", paramDataSource.getDataSourceInterface());
            // 如果是需要回调的接口，则补全回调地址
            completeRequestHelper.completeRequestParameter(merchPrivate, dataRequest);
            // 请求数据平台接口获取数据
            responseContent = dataRequestHandler.sendDataRequest(
                    requestOrderId,
                    merchPrivate.toJSONString(),
                    paramDataSource.getDataSourceInterface(),
                    dataRequest.getRequestJson().toJSONString());
        } catch (Exception e) {
            log.error("请求数据源时报错");
            log.error(e.getMessage(), e);
            throw new Exception(e.getMessage());
        }
        try {
            return parseAndSaveData(
                    userId,
                    dataRequest,
                    dataRequest.getDataSourceCode(),
                    responseContent,
                    orderCache);
        } catch (Exception e) {
            log.error("解析存储返回数据时报错");
            log.error(e.getMessage(), e);
            throw new Exception(e.getMessage());
        }
    }

    private DataResponse parseAndSaveData(Integer userId,
                                          DataRequest dataRequest,
                                          String dataSourceCode,
                                          String responseContent,
                                          JSONObject orderCache) {
        DataResponse dataResponse = DataResponse.build(RetEntity.PARSER_DATA_ERROR, Constant.ORDER_GET_DATA);
        dataResponse.setDataSourceCode(dataSourceCode);
        DataParser dataParser = dataParserGetter.getDataParser(dataSourceCode);
        if (dataParser != null) {
            boolean isParseOk = false;
            try {
                isParseOk = dataParser.parseAndSaveData(responseContent, dataResponse, userId);
            } catch (Exception e) {
                log.error("DataParser - 解析失败。");
                log.error(e.getMessage(), e);
            }
            if (isParseOk) {
                orderCache.put(dataSourceCode, "1");
                redisHelper.hset(CommonUtil.getDataSourceRedisKey(dataRequest.getOrderId(), userId), dataSourceCode, "1");
                try {
                    NotificationEntity sendingData = NotificationEntity.build(userId, dataRequest.getUsername(), dataRequest.getOrderId(), dataSourceCode);
                    log.info("发送到MQ的消息体为: {}", JSONObject.toJSONString(sendingData));
                    rabbitMqSender.sendMessage(sendingData);
                    dataResponse.setRetCode(RetEntity.SUCCESS.getCode());
                    dataResponse.setRetMessage(RetEntity.SUCCESS.getMessage());
                } catch (Exception e) {
                    log.error("发送清洗MQ报错");
                    log.error(e.getMessage(), e);
                    dataResponse.setRetCode(RetEntity.INNER_ERROR.getCode());
                    dataResponse.setRetMessage(RetEntity.INNER_ERROR.getMessage());
                    JSONObject msg = new JSONObject();
                    msg.put("msg", "通知规则引擎失败");
                    dataResponse.setResponseJson(msg);
                }
            }
        } else {
            log.warn("没有[{}]对应的请求响应解析器", dataSourceCode);
        }
        return dataResponse;
    }

    private String genDataRequestOrderId(DataRequest request) {
        Random ra = new Random();
        int ram = ra.nextInt(1000);
        return request.getOrderId() + "-" + ram;
    }
}
